import { expect } from '@ohos/hypium';
import ArkGameRaw from 'libarktsgame.so';

export  class   Color
{
  r:number=0;
  g:number=0;
  b:number=0;
  a:number=1;
}
enum GFX_CMD
{
  Clear=1,
  Mesh_Create=2,
  Mesh_Destory=3,
  DrawMesh=4,
}
enum PrimtiveType
{
  Point=1,
  Line=2,
  Triangle=3,
}
export  class    Helper
{
  regoutputv:DataView;
  reginputv:DataView;

  constructor() {
    this.reginputv =new DataView(ArkGameRaw.Gfx_GetRegInput());//得到输入寄存器
    this.regoutputv =new DataView(ArkGameRaw.Gfx_GetRegOutput());//得到输出寄存器
  }
  frameID:number=0;
  delta:number=0;
  Gfx_Init(oninit:()=>void,onupdate:()=>void):void  //done
  {
      var onupdate2 =()=>
      {
        this.delta = this.regoutputv.getFloat32(4,true)/1000; //ms=>second
        this.frameID = this.regoutputv.getUint32(0,true);
        onupdate();
      }
      ArkGameRaw.Gfx_Init(oninit,onupdate2);
  }
  Gfx_MeshCreate(vertexformat:VertexAttribute,maxvertex:number,maxindex:number,):Mesh
  {
    this.reginputv.setUint32(0,GFX_CMD.Mesh_Create,true);
    this.reginputv.setUint32(4,maxvertex,true);
    this.reginputv.setUint32(8,maxindex,true);

    this.reginputv.setUint8(12,vertexformat.HaveColor?1:0);
    this.reginputv.setUint8(13,vertexformat.HaveColor2?1:0);
    this.reginputv.setUint8(14,vertexformat.HaveNormal?1:0);
    this.reginputv.setUint8(15,vertexformat.HaveTangent?1:0);
    this.reginputv.setUint8(16,vertexformat.HaveWeight?1:0);

    ArkGameRaw.Gfx_Commit();
    var handle = this.regoutputv.getUint32(0,true);
    return new Mesh(handle,vertexformat,maxvertex,maxindex);
  }
  Gfx_MeshDestory(mesh:Mesh):void
  {
    this.reginputv.setUint32(0,GFX_CMD.Mesh_Destory);
    this.reginputv.setUint32(4,mesh.Handle,true);
    mesh.Destory();
    ArkGameRaw.Gfx_Commit();
  }
  Gfx_DrawMesh(mesh:Mesh,indexstart:number,indexcount:number):void
  {
    this.reginputv.setUint32(0,GFX_CMD.DrawMesh);
    this.reginputv.setUint32(4,mesh.Handle,true);
    this.reginputv.setUint32(4,mesh.indexstart,true);
    this.reginputv.setUint32(4,mesh.indexcount,true);
    this.reginputv.setUint32(12,mesh.primtiveType,true);
    ArkGameRaw.Gfx_Commit();
  }
  Clear(color:Color):void
  {
    this.reginputv.setUint32(0,1,true);
    this.reginputv.setFloat32(4,color.r,true);
    this.reginputv.setFloat32(8,color.g,true);
    this.reginputv.setFloat32(12,color.b,true);
    this.reginputv.setFloat32(16,color.a,true);
    ArkGameRaw.Gfx_Commit();
  }
}
//描述顶点信息的数据结构
export class VertexAttribute
{
  //pos xyz; layout 0
  private color:Boolean; //layout 1
  private color2:Boolean; //layout 2
  private normal:Boolean; //layout 3
  private tangent:Boolean; //layout 4
  private blendweight:Boolean;//layout 5;
  private colorpos:number;
  private color2pos:number;
  private normalpos:number;
  private tangentpos:number;
  private  blendweightpos:number;
  constructor(color:boolean,color2:boolean,normal:boolean,tangent:boolean,blendweight:boolean) {
    this.color=color;
    this.color2=color;
    this.normal=normal;
    this.tangent=tangent;
    this.blendweight=blendweight;
    var beginpos=12;
    if(this.color) {
      this.colorpos = beginpos;
      beginpos += 4;
    }
    if(this.color2) {
      this.color2pos = beginpos;
      beginpos += 4;//rgba32
    }
    if(this.normal) {
      this.normalpos = beginpos;
      beginpos += 12;//xyz
    }
    if(this.color) {
      this.tangentpos = beginpos;
      beginpos += 16;//xyzw;
    }
    if(this.blendweight){
      this.blendweightpos=beginpos;
      beginpos+= 32;//4 boneindex(int) + 4 weight(float)
    }
  }
  get HaveVertex():Boolean
  {
    return true;
  }
  get HaveColor():Boolean {
    return this.color;
  }
  get HaveColor2():Boolean {
  return this.color2;
  }
  get HaveNormal():Boolean
  {
    return this.normal;
  }
  get HaveTangent():Boolean
  {
    return this.tangent;
  }
  get HaveWeight():Boolean
  {
    return this.blendweight;
  }
  get PosVertex():number
  {
    return 0;
  }
  get PosColor():number
  {
    return this.colorpos;
  }
  get PosColor2():number
  {
    return this.color2pos;
  }
  get PosNormal():number
  {
    return this.normalpos;
  }
  get PosTangent():number
  {
    return this.tangentpos;
  }
  get PosWeight():number
  {
    return this.blendweightpos;
  }
}
export class Mesh
{
  private  vertexformat:VertexAttribute;
  private handle:number;
  private maxvertexCount:number
  private maxindexCount:number;
  public  get VertexFormat():VertexAttribute
  {
    return this.vertexformat;
  }
  public  get Handle() :number
  {
    return this.handle;
  }
  public  get  MaxVertexCount():number
  {
    return this.maxvertexCount;
  }
  public  get MaxIndexCount():number
  {
    return this.maxindexCount;
  }

  indexstart:number;
  indexcount:number;
  primtiveType:PrimtiveType;

  constructor(handle:number,vertexformat:VertexAttribute,maxvertex:number,maxindex:number) {
    this.vertexformat =vertexformat;
    this.handle=handle;
    this.maxvertexCount= maxvertex;
    this.maxindexCount =maxindex;
    this.indexstart=0;
    this.indexcount=maxindex;
    this.primtiveType=  PrimtiveType.Triangle;
  }
  Destory():void
  {
    this.handle=0;
  }
}